package com.gopay.cashier.service.riskcontrol.impl;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.cps.dao.order.CpsGeneralMainOrderQueryDAO;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.remote.order.MainOrderField;
import com.gopay.remote.order.MainOrderUpdateRemoteService;
import com.gopay.remote.riskcontrol.RiskControlRemoteService;
import com.gopay.remote.riskcontrol.vo.RiskControlInfo;
import com.gopay.remote.riskcontrol.vo.RiskControlResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.gopay.cashier.service.riskcontrol.CallRiskControlService;
import com.gopay.common.cipher.utils.LoggerMaskUtils;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.exception.GopayException;

/**
 * 调用风控服务Service
 * 
 * @CallRiskControlServiceImpl.java
 * @author fanghw
 * @2016年1月21日 下午4:49:09  www.gopay.com.cn Inc.All rights reserved.
 */
@Service("callRiskControlService")
public class CallRiskControlServiceImpl implements CallRiskControlService {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource(name="riskControlRemoteService")
    private RiskControlRemoteService riskControlRemoteService;

    @Resource(name = "mainOrderUpdateService")
    private MainOrderUpdateRemoteService mainOrderUpdateRemoteService;

    @Resource(name="cpsGeneralMainOrderQueryDAO")
    protected CpsGeneralMainOrderQueryDAO cpsGeneralMainOrderQueryDAO;

    @Override
    public void assess(String gopayOrderId, String payChannel, String cardNo, String payCustId) throws GopayException {
        //1.风控入参
        RiskControlInfo riskControlInfo = new RiskControlInfo();
        riskControlInfo.setGopayOrderId(gopayOrderId);
        riskControlInfo.setPayChannel(payChannel);
        riskControlInfo.setCardNo(cardNo);
        riskControlInfo.setPayCustId(payCustId);

        RiskControlResult result = null;

        try{
        	  /**start ---卡号日志掩码处理 ssj 2017-04-18*/
            logger.info("调用风控服务开始--入参 ：" + LoggerMaskUtils.maskString(riskControlInfo.toString()));
            /**end*/
            result = riskControlRemoteService.assess(riskControlInfo);
            logger.info("调用风控服务结束--出参 ：" + result.toString());

            if (result.getCallSuccess() && result.getRefuse()) {
                logger.info(gopayOrderId + "调用风控服务被拒绝，拒绝原因 ：" + result.getRefuseReason());

                //是否成功拒绝
                boolean isRefuseSuccess = false;
                //风控拒绝--更新主订单风控审核中...
                if(result.getErrCode().equals(ProcCodeConstants.PROC_CODE_200G1001)
                        || result.getErrCode().equals(ProcCodeConstants.PROC_CODE_200G3001)
                        || result.getErrCode().equals(ProcCodeConstants.PROC_CODE_200G3002) ){
                    try {

                        Map<MainOrderField, String> param = new HashMap<>();
                        Integer txnStaCode = TxnStaCode.TXN_STA_CD_30300.value;
                        if(result.getErrCode().equals(ProcCodeConstants.PROC_CODE_200G3001)){
                            txnStaCode = TxnStaCode.TXN_STA_CD_20002.value;
                            //快捷模型阻断交易需要记录err_msg  add by songfengli 20171211
                            param.put(MainOrderField.ERR_MSG, "违反快捷支付风险模型");
                        }

                        logger.info("调用cps更新主订单TxnStaCode = " + txnStaCode + " --start");
                        param.put(MainOrderField.TXN_STA_CD, txnStaCode.toString());
                        mainOrderUpdateRemoteService.updateMany(gopayOrderId, param);

                        logger.info("调用cps更新主订单TxnStaCode--end");
//                        throw new GopayException(result.getErrCode(), "外部风控拒绝");
                        isRefuseSuccess = true;
                    }catch (GopayException e1){
                        logger.error(gopayOrderId + "调用cps更新主订单失败，继续交易 :" + e1.getErrMsg());
                        return;
                    }catch (Exception e2){
                        logger.error(gopayOrderId + "调用cps更新主订单网络异常", e2);

                        //重查MainOrder判断是否更新成功
                        CpsGenMainOrder order = cpsGeneralMainOrderQueryDAO.find(CpsGenMainOrder.class, gopayOrderId);
                        logger.error("重查MainOrder状态 ：TXN_STA_CD = " + order.getTxnStaCd() +";");
                        if(order.getTxnStaCd() == TxnStaCode.TXN_STA_CD_30300.value){
                            logger.error("主订单状态【风控审核中】更新成功 ： 外部风控拒绝...");
//                            throw new GopayException(result.getErrCode(), "外部风控拒绝");
                            isRefuseSuccess = true;
                        }else {
                            logger.error("主订单状态【风控审核中】更新失败 ： 继续交易...");
                        }
                    }
                    if(isRefuseSuccess){
                        throw new GopayException(result.getErrCode(), "外部风控拒绝");
                    }
                }else{
                    throw new GopayException(result.getErrCode(), "外部风控拒绝");
                }
            }
        }catch (GopayException e){
            throw e;
        }catch (Exception ex){
            logger.error(gopayOrderId + "调用风控服务网络异常", ex);
        }

    }

}
